// RT-Thread头文件
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include <rtdevice.h>
#include <board.h>

// HAL库头文件
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "i2c.h"
#include "rt_thread_demo.h"
#include "../hardware/PWM/fly_pwm.h"             // PWM
#include "../hardware/IIC_BMP280/iic_bmp280.h"   // BMP280
#include "../hardware/IIC_BMP280/iic1.h"         // IIC

static bmp280_calib_data bmp280_calib;
static int32_t t_fine = 0;
static uint16_t BMP280_Read16(uint8_t reg); // 配合显示调用，消除警告使用

float Pressure = 0;// 压力值默认
float Temperature = 0; // 温度值默认

/****************************** IIC_BMP280_Init BEGIN **************************
 * 函    数：IIC_BMP280_Init
 * 功    能：初始化BMP280传感器，包括IIC总线初始化和BMP280传感器初始化
 * 参    数：无
 * 返 回 值：无
 * 注意事项：无
 ******************************************************************************/
void IIC_BMP280_Init(void)
{
    IIC1_init(); // 硬件IIC初始化
    BMP280_Read16(BMP280_REGISTER_DIG_T1); // 显示调用，消除警告使用
    if (!BMP280_Init())
    {
        rt_kprintf("BMP280 init failed!\n");
    }
    fly_control_init_status |= 0b00010000; // 成功标志位
}
/****************************** IIC_BMP280_Init END ****************************/

/****************************** BMP280_I2C_Read BEGIN **************************
 * 函    数：BMP280_I2C_Read
 * 功    能：通过IIC总线读取BMP280寄存器数据，使用HAL_I2C_Mem_Read函数实现
 * 参    数：dev_addr - 设备地址
 *           reg_addr - 寄存器地址
 *           data     - 存储读取数据的缓冲区
 *           len      - 读取数据的长度
 * 返 回 值：0 - 读取成功
 *          -1 - 读取失败
 * 注意事项：无
 ******************************************************************************/
int8_t BMP280_I2C_Read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
    int ret = HAL_I2C_Mem_Read(&hi2c1, dev_addr << 1, reg_addr, I2C_MEMADD_SIZE_8BIT, data, len, 100);
    if (ret != HAL_OK)
    {
        rt_kprintf("I2C Read error: reg=0x%02X, ret=%d\n", reg_addr, ret);
    }
    return ret == HAL_OK ? 0 : -1;
}
/****************************** BMP280_I2C_Read END ****************************/

/****************************** BMP280_I2C_Write BEGIN *************************
 * 函    数：BMP280_I2C_Write
 * 功    能：通过IIC总线写入BMP280寄存器数据，使用HAL_I2C_Mem_Write函数实现
 * 参    数：dev_addr - 设备地址
 *           reg_addr - 寄存器地址
 *           data     - 存储写入数据的缓冲区
 *           len      - 写入数据的长度
 * 返 回 值：0 - 写入成功
 *          -1 - 写入失败
 * 注意事项：无
 ******************************************************************************/
int8_t BMP280_I2C_Write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
    return HAL_I2C_Mem_Write(&hi2c1, dev_addr<<1, reg_addr, I2C_MEMADD_SIZE_8BIT, data, len, 100);
}
/****************************** BMP280_I2C_Write END ***************************/

// 读8位
static uint8_t BMP280_Read8(uint8_t reg)
{
    uint8_t value = 0;
    BMP280_I2C_Read(BMP280_I2C_ADDR, reg, &value, 1);
    return value;
}

// 读16位
static uint16_t BMP280_Read16(uint8_t reg)
{
    uint8_t buf[2];
    BMP280_I2C_Read(BMP280_I2C_ADDR, reg, buf, 2);
    return (buf[0] << 8) | buf[1];
}

// 读16位小端
static uint16_t BMP280_Read16_LE(uint8_t reg)
{
    uint8_t buf[2];
    BMP280_I2C_Read(BMP280_I2C_ADDR, reg, buf, 2);
    return (buf[1] << 8) | buf[0];
}

// 读有符号16位
static int16_t BMP280_ReadS16_LE(uint8_t reg)
{
    return (int16_t)BMP280_Read16_LE(reg);
}

// 写8位
static void BMP280_Write8(uint8_t reg, uint8_t value)
{
    BMP280_I2C_Write(BMP280_I2C_ADDR, reg, &value, 1);
}

// 读取校准参数
static void BMP280_ReadCoefficients(void)
{
    bmp280_calib.dig_T1 = BMP280_Read16_LE(BMP280_REGISTER_DIG_T1);
    bmp280_calib.dig_T2 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_T2);
    bmp280_calib.dig_T3 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_T3);
    bmp280_calib.dig_P1 = BMP280_Read16_LE(BMP280_REGISTER_DIG_P1);
    bmp280_calib.dig_P2 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_P2);
    bmp280_calib.dig_P3 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_P3);
    bmp280_calib.dig_P4 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_P4);
    bmp280_calib.dig_P5 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_P5);
    bmp280_calib.dig_P6 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_P6);
    bmp280_calib.dig_P7 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_P7);
    bmp280_calib.dig_P8 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_P8);
    bmp280_calib.dig_P9 = BMP280_ReadS16_LE(BMP280_REGISTER_DIG_P9);
}

/****************************** BMP280_Init BEGIN ******************************
 * 函    数：BMP280_Init
 * 功    能：初始化BMP280传感器
 * 参    数：无
 * 返 回 值：0 - 初始化失败
 *           1 - 初始化成功
 * 注意事项：无
 ******************************************************************************/
uint8_t BMP280_Init(void)
{
    uint8_t id = BMP280_Read8(BMP280_REGISTER_CHIPID);
    if (id != 0x58) return 0;
    BMP280_ReadCoefficients();
    BMP280_Write8(BMP280_REGISTER_CONTROL, 0x3F); // 推荐配置
    return 1;
}
/****************************** BMP280_Init END ********************************/

/****************************** BMP280_ReadTemperature BEGIN *******************
 * 函    数：BMP280_ReadTemperature
 * 功    能：读取BMP280传感器的温度数据
 * 参    数：无
 * 返 回 值：温度值（单位：摄氏度）
 * 注意事项：无
 ******************************************************************************/
float BMP280_ReadTemperature(void)
{
    int32_t var1, var2;
    int32_t adc_T = ((BMP280_Read8(BMP280_REGISTER_TEMPDATA) << 12) |
                     (BMP280_Read8(BMP280_REGISTER_TEMPDATA + 1) << 4) |
                     (BMP280_Read8(BMP280_REGISTER_TEMPDATA + 2) >> 4));
    var1 = ((((adc_T >> 3) - ((int32_t)bmp280_calib.dig_T1 << 1))) *
            ((int32_t)bmp280_calib.dig_T2)) >> 11;
    var2 = (((((adc_T >> 4) - ((int32_t)bmp280_calib.dig_T1)) *
              ((adc_T >> 4) - ((int32_t)bmp280_calib.dig_T1))) >> 12) *
            ((int32_t)bmp280_calib.dig_T3)) >> 14;
    t_fine = var1 + var2;
    float T = (t_fine * 5 + 128) >> 8;
    return T / 100;
}
/****************************** BMP280_ReadTemperature END *********************/

/****************************** BMP280_ReadPressure BEGIN ***********************
 * 函    数：BMP280_ReadPressure
 * 功    能：读取BMP280传感器的压力数据
 * 参    数：无
 * 返 回 值：压力值（单位：帕斯卡，float型）
 * 注意事项：返回值为浮点数，单位为帕斯卡（Pa）
 ******************************************************************************/
float BMP280_ReadPressure(void)
{
    int64_t var1, var2, p;
    int32_t adc_P = ((BMP280_Read8(BMP280_REGISTER_PRESSUREDATA) << 12) |
                     (BMP280_Read8(BMP280_REGISTER_PRESSUREDATA + 1) << 4) |
                     (BMP280_Read8(BMP280_REGISTER_PRESSUREDATA + 2) >> 4));
    var1 = ((int64_t)t_fine) - 128000;
    var2 = var1 * var1 * (int64_t)bmp280_calib.dig_P6;
    var2 = var2 + ((var1 * (int64_t)bmp280_calib.dig_P5) << 17);
    var2 = var2 + (((int64_t)bmp280_calib.dig_P4) << 35);
    var1 = ((var1 * var1 * (int64_t)bmp280_calib.dig_P3) >> 8) +
           ((var1 * (int64_t)bmp280_calib.dig_P2) << 12);
    var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)bmp280_calib.dig_P1) >> 33;
    if (var1 == 0) return 0;
    p = 1048576 - adc_P;
    p = (((p << 31) - var2) * 3125) / var1;
    var1 = (((int64_t)bmp280_calib.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
    var2 = (((int64_t)bmp280_calib.dig_P8) * p) >> 19;
    p = ((p + var1 + var2) >> 8) + (((int64_t)bmp280_calib.dig_P7) << 4);
    return (float)p / 256;
}
/****************************** BMP280_ReadPressure END ************************/
